﻿/* ----------------------------------------------------------------------------
 * Copyright (c) Philip Stears 
 *
 * This source code is subject to terms and conditions of the Microsoft Public 
 * License (Ms-PL).
 * 
 * By using this source code in any fashion, you are agreeing to be bound 
 * by the terms of the Microsoft Public License.
 * 
 * To request a copy of the Microsoft Public License, send a request by email
 * to license@connectbasic.net.
 *
 * This notice must not be removed from this software.
 * ---------------------------------------------------------------------------- */

namespace ConnectBasic.Shell.Implementation
{
    using System.Threading;
    using ConnectBasic.Execution;
    using ConnectBasic.Shell.Extensibility;
    using System;

    internal class BasicMacro : IExecutableMacro
    {
        private BasicFunction mFunction;

        #region .ctor

        internal BasicMacro(BasicFunction function)
        {
            mFunction = function;
        }

        #endregion

        #region IExecutableMacro Members

        public event EventHandler Started;

        public event EventHandler Finished;

        public string Name
        {
            get { return mFunction.Name; }
        }

        public void Execute()
        {
            // Execute the macro on another thread so that debugging doesn't 
            // freeze the UI
            var macroThread = new Thread(
                delegate()
                {
                    this.RaiseStarted();
                    mFunction.GetCallableDelegate().DynamicInvoke();
                    this.RaiseFinished();
                }
                );

            macroThread.IsBackground = true;
            macroThread.Name = "Macro Execution Thread: " + mFunction.Name;
            macroThread.Start();            
        }

        #endregion

        #region Private Helpers
        
        private void RaiseStarted()
        {
            EventHandler evt = Started;

            if (evt != null)
            {
                evt(this, EventArgs.Empty);
            }
        }

        private void RaiseFinished()
        {
            EventHandler evt = Finished;

            if (evt != null)
            {
                evt(this, EventArgs.Empty);
            }
        }

        #endregion

    }
}
